package com.hy.springboot.common.filter;

import com.hy.springboot.common.constant.Constant;
import com.hy.springboot.common.utils.MDCUtils;
import com.hy.springboot.common.utils.StrUtils;
import com.hy.springboot.common.utils.TraceIdUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.ListenableFilter;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcContext;

@Activate(group = {CommonConstants.PROVIDER,CommonConstants.CONSUMER})
public class RpcTraceIdFilter  extends ListenableFilter {
    @Override
    public Result invoke(org.apache.dubbo.rpc.Invoker<?> invoker, org.apache.dubbo.rpc.Invocation invocation) throws org.apache.dubbo.rpc.RpcException {
        String traceId = RpcContext.getContext().getAttachment(Constant.TRACE_ID);
        String threadTranceId = TraceIdUtils.getTraceId();
        String newTraceId =  StrUtils.randomStringUpper(32);
        if (StringUtils.isNotEmpty(traceId) ) {
            // *) 从RpcContext里获取traceId并保存
            RpcContext.getContext().setAttachment(Constant.TRACE_ID,traceId);
            MDCUtils.set(traceId);
        }else if (StringUtils.isNotBlank(threadTranceId)){
            RpcContext.getContext().setAttachment(Constant.TRACE_ID,threadTranceId);
            MDCUtils.set(threadTranceId);
        } else {
            // *) 交互前重新设置traceId, 避免信息丢失
            RpcContext.getContext().setAttachment(Constant.TRACE_ID,newTraceId);
            MDCUtils.set(newTraceId);
        }
        // *) 实际的rpc调用
        return invoker.invoke(invocation);
    }
}
